import type { Component } from 'vue'
import {
  NInput,
  NSwitch,
  NInputNumber,
  NTreeSelect,
  NSelect,
  NDatePicker,
  NRadioGroup,
  NRadio,
  NCheckboxGroup,
  NCheckbox,
} from 'naive-ui'
import { isString } from 'lodash-es'
import UploadImage from '@/components/autoimport/UploadImageLocal.vue'
import UploadImageListLocal from '@/components/autoimport/UploadImageListLocal.vue'
import UploadFileLocal from '@/components/autoimport/UploadFileLocal.vue'
import YQuil from '@/components/yang/YQuil.vue'

/**
 * 由于 naive-ui 组件许多都是 v-model:value 绑定的，为了统一处理，使用这个函数将组件转换为支持 v-model 的组件。
 * 将传入的组件转换为支持 v-model 双向绑定的组件。
 * @param component 要转换为支持 v-model 的 Vue 组件
 * @param key 绑定属性的名称，默认为 'value'
 * @returns 返回一个新的包装组件，支持 v-model 绑定
 */
export function transformModelValue(component: Component, key = 'value'): Component {
  return defineComponent({
    setup(props: Record<string, unknown>, { attrs, slots, emit }) {
      return () => {
        const { modelValue, ..._props } = { ...props, ...attrs }
        return h(
          component, // NInput
          {
            ..._props,
            [key]: modelValue, // v-model
            [`onUpdate:${key}`]: (val) => emit('update:modelValue', val),
            // emit.bind(null, 'update:modelValue'), // v-model
          },
          slots,
        )
      }
    },
  })
}
function transformOptions(component: Component, optionsComponent: Component) {
  return (props: { options: { label: string; value: string; slots? }[] }, { slots }) => {
    const { options = [] } = props
    return h(transformModelValue(component), props, () => {
      return options.map((item) => {
        let _slots = item.slots
        if (typeof _slots === 'string') {
          _slots = slots[_slots]
        }
        return h(optionsComponent, item, _slots)
      })
    })
  }
}
const bindingKeyMap = new Map([
  ['input', 'modelValue'],
  ['datePickerFormat', 'formatted-value'],
])
const formItemMap = new Map<string, Component>([
  ['input', transformModelValue(NInput)], // v-model:value AInput
  ['select', transformModelValue(NSelect)],
  ['number', transformModelValue(NInputNumber)],
  ['switch', transformModelValue(NSwitch)],
  ['radio', transformOptions(NRadioGroup, NRadio)],
  ['checkbox', transformOptions(NCheckboxGroup, NCheckbox)],
  ['datePicker', transformModelValue(NDatePicker)],
  ['datePickerFormat', transformModelValue(NDatePicker, 'formatted-value')],
  ['tree-select', transformModelValue(NTreeSelect)],
  ['image', UploadImage],
  ['imageList', UploadImageListLocal],
  ['file', UploadFileLocal],
  ['rich', YQuil],
])
export const getFormItemComponent = (type?: string | Component): Component => {
  // 如果不是一个字符串，我就认定你是一个组件
  if (type && !isString(type)) return type as Component
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-expect-error
  return (type && formItemMap.get(type)) || formItemMap.get('input')
}

export const getBindingKey = (type?: string): string => {
  if (!type) return 'modelValue'
  return bindingKeyMap.get(type) || 'modelValue'
}
